package services;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

public class TemplateReader {

	public static String read(Object obj, String resource, String... arg) {
		BufferedReader br = new BufferedReader(new InputStreamReader(obj
				.getClass().getResourceAsStream(resource)));
		StringBuilder sb = new StringBuilder();
		String s;
		try {
			while ((s = br.readLine()) != null) {
				if (!s.trim().startsWith("#")) {
					// si no es un comentario de línea
					sb.append(replaceArgument(s, arg)).append('\n');
				}
			}
			br.close();
			return sb.toString();
		} catch (IOException ioe) {
			return ioe.getMessage();
		}
	}

	private static StringBuilder replaceArgument(String line, String... arg) {
		StringBuilder sb = new StringBuilder(line);
		for (int i = 0; i < arg.length; i++) {
			String argValue = arg[i];
			String argName = "{" + i + "}";
			int ndx = sb.indexOf(argName);
			while (ndx != -1) {
				sb.replace(ndx, ndx + argName.length(), argValue);
				ndx = sb.indexOf(argName, ndx);
			}
		}
		return sb;
	}

	/**
	 * List directory contents for a resource folder. Not recursive. This is
	 * basically a brute-force implementation. Works for regular files and also
	 * JARs.
	 * 
	 * @author Greg Briggs
	 * @param clazz
	 *            Any java class that lives in the same place as the resources
	 *            you want.
	 * @param path
	 *            Should end with "/", but not start with one.
	 * @return Just the name of each member item, not the full paths.
	 * @throws URISyntaxException
	 * @throws IOException
	 */
	private static String[] getResourceListing(Class<?> cls, String path)
			throws URISyntaxException, IOException {
		URL dirURL = cls.getClassLoader().getResource(path);
		if (dirURL != null && dirURL.getProtocol().equals("file")) {
			/* A file path: easy enough */
			return new File(dirURL.toURI()).list();
		}

		if (dirURL == null) {
			/*
			 * In case of a jar file, we can't actually find a directory. Have
			 * to assume the same jar as clazz.
			 */
			String me = cls.getName().replace(".", "/") + ".class";
			dirURL = cls.getClassLoader().getResource(me);
		}

		if (dirURL.getProtocol().equals("jar")) {
			/* A JAR path */
			String jarPath = dirURL.getPath().substring(5,
					dirURL.getPath().indexOf("!")); // strip out only the JAR
													// file
			JarFile jar = new JarFile(URLDecoder.decode(jarPath, "UTF-8"));
			Enumeration<JarEntry> entries = jar.entries(); // gives ALL entries
															// in jar
			Set<String> result = new HashSet<String>(); // avoid duplicates in
														// case it is a
														// subdirectory
			while (entries.hasMoreElements()) {
				String name = entries.nextElement().getName();
				if (name.startsWith(path)) { // filter according to the path
					String entry = name.substring(path.length());
					int checkSubdir = entry.indexOf("/");
					if (checkSubdir >= 0) {
						// if it is a subdirectory, we just return the directory
						// name
						entry = entry.substring(0, checkSubdir);
					}
					result.add(entry);
				}
			}
			return result.toArray(new String[result.size()]);
		}

		throw new UnsupportedOperationException("Cannot list files for URL "
				+ dirURL);
	}

	public static void searchTemplates(Class<?> clazz, String path) {
		try {
			String[] list = getResourceListing(clazz, "services/");
			for (String s : list) {
				if (s.endsWith(".template.txt")) {
					System.out.println(s);
				}
			}
		} catch (IOException ioe) {
		} catch (URISyntaxException uriE) {
		}
	}
}
